package roborally.program.command;

import be.kuleuven.cs.som.annotate.Basic;
import be.kuleuven.cs.som.annotate.Immutable;
import be.kuleuven.cs.som.annotate.Raw;

/**
 * A class representing a command that can need arguments in order to be executed/evaluated.
 * 
 * @invar An ArgumentCommand must have legal arguments, as defined in the method canHaveAsArguments() at all times.
 * 		| this.canHaveAsArguments(this.getArguments())
 * 
 * @author Molderez Tom, 2de bach Ingenieurswetenschappen Computerwetenschappen-Elektrotechniek and Reniers Jorn, 2de bach Ingenieurswetenschappen Werktuigkunde-Computerwetenschappen
 * @version 1.0
 *
 */
public abstract class ArgumentCommand extends Command {

	/**
	 * Create a new ArgumentCommand with the given arguments.
	 * 
	 * @param arguments The arguments of this command.
	 * @post The arguments of the new ArgumentCommand will be equal to the given arguments?
	 * 		| (new this).getArguments() == arguments
	 * @throws IllegalArgumentException
	 * 		When the arguments are not valid according to isPossibleArguments().
	 * 		| !isPossibleArguments(arguments)
	 */
	protected ArgumentCommand(Object...arguments) throws IllegalArgumentException {
		super();
		if(!isPossibleArguments(arguments))
			throw new IllegalArgumentException("Illegal arguments for an Argumentcommand");
		this.arguments = arguments;
	}
	
	/**
	 * Returns the extra arguments that might be needed for this command.
	 */
	@Basic
	@Raw
	@Immutable
	public Object[] getArguments() {
		return arguments;
	}

	/**
	 * Controls if the given arguments are valid.
	 * 
	 * @param arguments The arguments to be controlled.
	 * @return If the arguments are not possible according to isPossibleArguments(), then the result is false.
	 * 		| if !isPossibleArguments(arguments)
	 * 		|	then result == false
	 */
	public boolean canHaveAsArguments(Object...arguments) {
		return isPossibleArguments(arguments);
	}
	
	/**
	 * Controls if the given arguments are possible. On this stage, every arguments, also null, is possible.
	 * 
	 * @param arguments The arguments to be controlled.
	 */
	public boolean isPossibleArguments(Object...arguments) {
		return true; //null moet legaal zijn.
	}
	
	/**
	 * The arguments of this ArgumentCommand.
	 */
	private final Object[] arguments;
}